from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException
from app.config import config
import datetime
import json
import redis
import time
import sys


r = redis.Redis('localhost', port=6379, db=1, decode_responses=True)


options = webdriver.ChromeOptions()
# if r.get('jd') is not None:
#     options.add_argument('--headless')
browser = webdriver.Chrome(options=options)
wait = WebDriverWait(browser, 10)


# 消费
class Consumer(object):
    # 初始化参数
    def __init__(self, *args, **kwargs):
        for key, val in kwargs.items():
            setattr(self, key, val)
        self.browser = browser
        self.wait = wait
        print('任务时间: {}'.format(self.task_at))

    # 当前时间
    def current_datetime(self):
        return '[{}]'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

    # 登陆
    def login(self):
        self.browser.get('https://passport.jd.com/new/login.aspx')
        print('{} 用户登陆...'.format(self.current_datetime()))
        if r.get('jd') is None:
            while True:
                try:
                    self.wait.until(
                        EC.text_to_be_present_in_element((
                            By.CSS_SELECTOR,
                            '#shortcut > div > ul.fr > li.shortcut_btn.fore2 > div > a'
                        ), '我的订单'))
                    r.set('jd', json.dumps(self.browser.get_cookies()))
                    break
                except TimeoutException:
                    print('继续等待扫码获取')
        else:
            print('{} 查到有cookies, 使用此身份登陆.'.format(self.current_datetime()))

        listCookies = json.loads(r.get('jd'))
        self.browser.delete_all_cookies()

        for cookie in listCookies:
            self.browser.add_cookie(cookie)
        print('{} 登陆成功'.format(self.current_datetime()))

    # 指定时间执行
    def timing(self):
        start_time = datetime.datetime.strptime(self.task_at, '%Y-%m-%d %H:%M:%S')
        while datetime.datetime.now() < start_time:
            sys.stdout.write('当前时间: {}\r'.format(self.current_datetime()))
            time.sleep(1)

    # 提交订单
    def submit_order(self):
        print('{} 打开订单'.format(self.current_datetime()))
        self.browser.get(self.order_url)

    # 是否验证条件，等待出现指定价格, 出现后跳出循环
    def checkout_select(self):
        num = 0
        while True:
            try:
                self.wait.until(
                    EC.presence_of_element_located((
                        By.CSS_SELECTOR,
                        '#payChannelListId > div:nth-child(5) > div > div:nth-child(6) > a'
                    )))

                price = self.browser.find_element_by_xpath(
                    '//b[contains(text(),"300")]')
                if price:
                    print('找到了300块,支付中')
                    break
            except NoSuchElementException:
                self.browser.refresh()
                num += 1
                print('没有找到,尝试刷新页面, 次数:{}'.format(num))

    # 收银台支付
    def checkstand(self, is_checkout=False):
        print('{} 进入支付页面'.format(self.current_datetime()))
        assert '收银台' in self.browser.title, '没有成功进入收银台'
        if is_checkout:
            self.checkout_select()
            print('{} 验证条件成功'.format(self.current_datetime()))

        # 选择银行
        self.wait.until(
            EC.presence_of_element_located(
                (By.XPATH, '//strong[text()="{}"]'.format(self.pay_name)))).click()

        # 输入支付密码
        self.wait.until(
            EC.presence_of_element_located((
                By.CSS_SELECTOR,
                '#payChannelListId > div:nth-child(5) > div > div.pv-line.pv-line-shortPwd > span > input:nth-child(1)'
            ))).send_keys(self.pass_pay)

        print('{} 点击支付'.format(self.current_datetime()))

        # 确认支付
        self.wait.until(
            EC.presence_of_element_located((
                By.CSS_SELECTOR,
                '#payChannelListId > div:nth-child(5) > div > div:nth-child(6) > a'
            ))).click()

        # 验证是否成功
        try:
            self.wait.until(
                EC.text_to_be_present_in_element((
                    By.CSS_SELECTOR,
                    '#resultArea > div.porm-result-area.clearfix > div.pay-result-infor-box > div.result-infor-con > p:nth-child(2)'
                ), '购买成功'))
            print('完成支付成功')
        except NoSuchElementException:
            print('未完成，其它返回异常')

    # 主操作
    def run(self):
        # 登陆
        self.login()

        # 处理订单
        self.submit_order()

        # 指定时间执行
        self.timing()

        # 支付提交
        self.checkstand()


for item in config:
    jd = Consumer(**item).run()
